package schema;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jhunter.common.exception.ConfigException;

public abstract class Node {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private Node parent;

	/**
	 * key context
	 */
	private Map<String, Node> children = new LinkedHashMap<String, Node>();

	private String file;

	private String contextPath;

	/**
	 * 加载资源文件用的 class loader
	 * 
	 * @return
	 */
	abstract protected ClassLoader getClassLoader();

	protected String getFilePath(String resource) {
		File file = new File(getClassLoader().getResource(resource).getFile());
		return file.getPath();
	}

	protected InputStream setFileAndReturnStream(String path) {
		File f = new File(path);
		InputStream is = null;
		if (!f.exists()) {
			file = getFilePath(path);
			is = getClassLoader().getResourceAsStream(path);
		} else {
			file = path;
			try {
				is = new FileInputStream(f);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				throw new ConfigException(e);
			}
		}
		logger.debug("load xml file : {}", path);
		return is;
	}

	public Node getParent() {
		return parent;
	}

	public void setParent(Node parent) {
		this.parent = parent;
	}


	public String getFile() {
		return file;
	}

	public void setFile(String file) {
		this.file = file;
	}

	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		String a = contextPath;
		if (contextPath.startsWith("/")) {
			contextPath = contextPath.substring(1);
		}
		if (contextPath.endsWith("/")) {
			contextPath = contextPath.substring(0, contextPath.length());
		}
		if (contextPath.indexOf("/") > -1) {
			throw new ConfigException("base context 不能包含 '/' [" + a + "]");
		}
		this.contextPath = contextPath;
	}

	public Map<String, Node> getChildren() {
		return children;
	}

	public void setChildren(Map<String, Node> children) {
		this.children = children;
	}

}
